上篇講完 Message Event 基本介紹後,今天就來整理 Postback 的資訊並時做一個簡單的 postback 機器人來熟悉一下。
postback event 是配合 postback action 的訊息事件,此種訊息不會被使用者看到,他在 postback action 被觸發時透過 API 將資訊內容(postback.data)傳送到 server 給程式或是系統做後續處理,因此可以利用它做使用者點擊按鈕後的後續動作或是蒐集資料等等。編編認為在設計服務上是很實用的功能₍₍◝(・'ω'・)◟⁾⁾。
// Postback event for date-time selection action
{
"destination": "xxxxxxxxxx",
"events": [
{
"replyToken": "b60d432864f44d079f6d8efe86cf404b",
"type": "postback",
"mode": "active",
"source": {
"userId": "U91eeaf62d...",
"type": "user"
},
"timestamp": 1513669370317,
"webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR",
"deliveryContext": {
"isRedelivery": false
},
"postback": {
"data": "storeId=12345",
"params": {
"datetime": "2017-12-25T01:00"
}
}
}
]
}
// Postback event for rich menu switch action
{
"destination": "xxxxxxxxxx",
"events": [
{
"replyToken": "b60d432864f44d079f6d8efe86cf404b",
"type": "postback",
"mode": "active",
"source": {
"userId": "U91eeaf62d...",
"type": "user"
},
"timestamp": 1619754620404,
"webhookEventId": "01FZ74A0TDDPYRVKNK77XKC3ZR",
"deliveryContext": {
"isRedelivery": false
},
"postback": {
"data": "richmenu-changed-to-b",
"params": {
"newRichMenuAliasId": "richmenu-alias-b",
"status": "SUCCESS"
}
}
}
]
}
更詳細的屬性介紹可以看 官方文件 喔!
知道了 postback event 基本知識後就要開始動手練習了~
*記得要設定好 Webhook URL 喔(後面加 /callback)
根據選擇按鈕的回傳文字,會回傳文字訊息及圖片。
這裡我設定當使用者輸入「成員介紹」時會出現三個按鈕選擇。且將要執行的程式碼放到 fun.py 來寫,讓 view.py 保持乾淨。
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from urllib.parse import parse_qsl
from linebot import LineBotApi, WebhookParser
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import *
from module import func
line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
parser = WebhookParser(settings.LINE_CHANNEL_SECRET)
@csrf_exempt
def callback(request):
if request.method == 'POST':
signature = request.META['HTTP_X_LINE_SIGNATURE']
body = request.body.decode('utf-8')
try:
events = parser.parse(body, signature)
except InvalidSignatureError:
return HttpResponseForbidden()
except LineBotApiError:
return HttpResponseBadRequest()
for event in events:
if isinstance(event, MessageEvent):
mtext = event.message.text
if mtext == '成員介紹':
func.sendIntro(event)
elif mtext == '第一隻喵':
func.sendcat01(event)
elif mtext == '第二隻喵':
func.sendcat02(event)
elif mtext == '第三隻喵':
func.sendcat03(event)
from django.conf import settings
from linebot import LineBotApi
from linebot.models import *
line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
def sendIntro(event):
try:
message = TemplateSendMessage(
alt_text='Buttons template',
template = ButtonsTemplate(
thumbnail_image_url="https://images.pexels.com/photos/160755/kittens-cats-foster-playing-160755.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
title='成員介紹',
text='請選擇',
actions=[
MessageTemplateAction(
label='第一隻喵',
text='第一隻喵'
),
MessageTemplateAction(
label='第二隻喵',
text='第二隻喵'
),
MessageTemplateAction(
label='第三隻喵',
text='第三隻喵'
)
]
)
)
line_bot_api.reply_message(event.reply_token,message)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
def sendcat01(event):
try:
message_A = []
message_A.append(TextSendMessage(text="我是喵仔"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
preview_image_url="https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
def sendcat02(event):
try:
message_A = []
message_A.append(TextSendMessage(text="我是毛毛"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/257532/pexels-photo-257532.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
preview_image_url="https://images.pexels.com/photos/257532/pexels-photo-257532.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
def sendcat03(event):
try:
message_A = []
message_A.append(TextSendMessage(text="我是嚕嚕"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/1404819/pexels-photo-1404819.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
preview_image_url="https://images.pexels.com/photos/1404819/pexels-photo-1404819.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
手機上樣子!
現在將原本透過判定使用者輸入的文字做反應的做改為用 postback 呼叫。
for event in events:
if isinstance(event, MessageEvent):
mtext = event.message.text
if mtext == '成員介紹':
func.sendIntro(event)
if isinstance(event, PostbackEvent):
backdata = dict(parse_qsl(event.postback.data))
if backdata.get('action') == '第一隻喵':
func.sendBack_cat01(event, backdata)
elif backdata.get('action') == '第二隻喵':
func.sendBack_cat02(event,backdata)
elif backdata.get('action') == '第三隻喵':
func.sendBack_cat03(event,backdata)
def sendIntro(event):
try:
message = TemplateSendMessage(
alt_text='Buttons template',
template = ButtonsTemplate(
thumbnail_image_url="https://images.pexels.com/photos/160755/kittens-cats-foster-playing-160755.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
title='成員介紹',
text='請選擇',
actions=[
PostbackTemplateAction(
label='第一隻喵',
text='第一隻喵_postback',
data='action=第一隻喵'
),
PostbackTemplateAction(
label='第二隻喵_postback',
text='第二隻喵_postback',
data='action=第二隻喵'
),
PostbackTemplateAction(
label='第三隻喵_postback',
data='action=第三隻喵'
)
]
)
)
line_bot_api.reply_message(event.reply_token,message)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
記得 fuc 後面參數有加因此此處要記得修改名稱~
def sendBack_cat01(event, backdata):
try:
message_A = []
message_A.append(TextSendMessage(text="我是喵仔"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1.png",
preview_image_url="https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1.png"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
def sendBack_cat02(event,backdata):
try:
message_A = []
message_A.append(TextSendMessage(text="我是毛毛"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/257532/pexels-photo-257532.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
preview_image_url="https://images.pexels.com/photos/257532/pexels-photo-257532.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
def sendBack_cat03(event,backdata):
try:
message_A = []
message_A.append(TextSendMessage(text="我是嚕嚕"))
message_A.append(ImageSendMessage(
original_content_url="https://images.pexels.com/photos/1404819/pexels-photo-1404819.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
preview_image_url="https://images.pexels.com/photos/1404819/pexels-photo-1404819.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
))
line_bot_api.reply_message(event.reply_token,message_A)
except:
line_bot_api.reply_message(event.reply_token,TextSendMessage(text='失敗'))
這樣就完成了簡單的練習喔(❀╹◡╹)!
小結尾:
在第一部份中跟著鐵人賽的腳步,學習與複習LINE Bot的各種基礎功能介紹,對編編們算是初學者來說非常的獲益良多,幸好擁有參加鐵人賽的機會讓編編們學習用Python完成Line Bot的服務,雖然已學習完基本功能,但也不可以停下腳步,有更深入更實用的小技巧以及實作,對未來的應用或是比賽甚至職場上,才真正可以派上用場,接下來幾天踏上實作之旅一起動手試試看吧(๑•̀ㅂ•́)و✧